<template>
  <div class="manual-call-name">
    <CustomSearch ref="searchRef" v-model:form="form" @search="getData">
      <template #moreHandle>
        <el-button type="primary" @click="selectAll" :disabled="jshList.length == 0"> <i class="iconfont icon-quanxuan"></i>全选</el-button>
        <el-button type="primary" @click="clearSelect" :disabled="jshList.length == 0">
          <el-icon><Delete /></el-icon> 清除选项</el-button
        >
        <el-button type="primary" @click="start" :disabled="jshList.length == 0"> <i class="iconfont icon-kaishi1"></i> 开始点名</el-button>
      </template>
    </CustomSearch>
    <div class="box" v-if="jshList.length > 0">
      <div v-if="isStart" class="calling">
        正在点名人数: {{ callingNumber }}人，<span style="color: #67c23a">成功 {{ successNum }}人</span>，<span style="color: red">失败 {{ failNum }}人。</span>
      </div>
      <el-scrollbar height="835rem" v-loading="loading">
        <div class="wrap">
          <div class="room" v-for="item in jshList" :key="item.jsh" @click="selectRoom(item)">
            <div class="room-name flex-center">
              {{ item.jsmc }}
              <el-button v-if="item.doWhat" type="primary" plain size="small" @click.stop="view(item)">详情</el-button>
            </div>
            <div class="room-detail">
              <CustomEchart
                type="gauge"
                width="72%"
                height="95%"
                :option="{
                  series: [
                    {
                      type: 'gauge',
                      center: ['50%', '60%'],
                      // radius: '20%',
                      startAngle: 200,
                      endAngle: -20,
                      min: 0,
                      max: item.cm,
                      splitNumber: 12,
                      itemStyle: {
                        color: '#6798B8'
                      },
                      progress: {
                        show: true,
                        width: 15
                      },
                      pointer: {
                        show: false
                      },
                      axisLine: {
                        lineStyle: {
                          width: 15,
                          color: '#C2C2C2',
                          color: [[1, '#C2C2C2']]
                        }
                      },
                      axisTick: {
                        distance: -25,
                        splitNumber: 3,
                        lineStyle: {
                          width: 0.2,
                          color: '#999'
                        }
                      },
                      splitLine: {
                        distance: -32,
                        length: 6,
                        lineStyle: {
                          width: 0.5,
                          color: '#999'
                        }
                      },
                      axisLabel: {
                        show: false,
                        distance: -20,
                        color: '#999',
                        fontSize: 12
                      },
                      anchor: {
                        show: false
                      },
                      title: {
                        show: false
                      },
                      detail: {
                        valueAnimation: true,
                        width: '60%',
                        lineHeight: 20,
                        borderRadius: 8,
                        offsetCenter: [0, '-15%'],
                        fontSize: 14,
                        fontWeight: 'bolder',
                        formatter: function (value) {
                          return item.cm + '\n' + '监室人数'
                        },
                        color: '#2F4050'
                      },
                      data: [
                        {
                          value: item.success
                        }
                      ]
                    }
                  ]
                }"
              ></CustomEchart>
              <div class="number">
                <div class="success">
                  {{ item.success || 0 }}
                  <div>成功人数</div>
                </div>
                <div class="fail">
                  {{ item.fail || 0 }}
                  <div>失败人数</div>
                </div>
              </div>
              <div class="status" :style="{ color: item.status == '正在监室点名中...' ? '#409eff' : item.status == '正常结束' ? '#67C23A' : 'red' }">{{ item.starting === true && !item.status ? '点名失败' : item.status }}</div>
            </div>
            <label v-if="item.selected" class="selected-label flex-center"
              ><el-icon color="#fff"><Select /></el-icon
            ></label>
          </div>
        </div>
      </el-scrollbar>
    </div>
    <CustomEmpty v-else height="896rem" style="margin-top: 10rem"></CustomEmpty>
    <CustomDialog title="点名详情" top="5vh" width="80%" height="950rem" v-model:dialogVisible="dialogVisible" confirmText="关闭" @confirm="dialogVisible = false">
      <Persons v-model:list="callingList" />
    </CustomDialog>
  </div>
</template>

<script setup name="manualCallName">
import { ref, onBeforeMount, onMounted, computed, watch, onBeforeUnmount } from 'vue'
import { http } from '@/utils/index.js'
import { stores } from '@/stores/index.js'
import Stomp from 'stompjs'
import { ElMessage, ElMessageBox } from 'element-plus'

let stompClient = null
let timer = null //websoket  断开重连定时器
let wsData = {} //websoket地址信息
const status = ref('点名失败') //点名结果
const useStore = stores.useUserStore()
const isSelectedAll = ref(false)
const isStart = ref(false)
const loading = ref(false)
const dialogVisible = ref(false)
const callingNumber = ref(0)
const jshList = ref([])
const callingList = ref([])
const props = defineProps({})
const form = ref({
  jq: ''
})
const option = ref({
  series: [
    {
      data: [
        {
          value: 20
        }
      ]
    }
  ]
})

const successNum = computed(() => {
  let num = 0
  jshList.value.forEach((item) => {
    if (item.success) {
      num = num + item.success * 1
    }
  })
  return num
})
const failNum = computed(() => {
  let num = 0
  jshList.value.forEach((item) => {
    if (item.fail) {
      num = num + item.fail * 1
    }
  })
  return num
})
onBeforeUnmount(() => {
  clearTimeout(timer)
  if (stompClient !== null) {
    stompClient.disconnect()
  }

  window.removeEventListener('beforeunload', handleBeforeunload)
})
onMounted(() => {
  getData()
  getWsUrl()
  window.addEventListener('beforeunload', handleBeforeunload)
})
const getData = (params = {}) => {
  loading.value = true
  http('/znjszd3/count/getRyCountGroupByJsh', 'get', params)
    .then((res) => {
      jshList.value = res.data.jshlist
    })
    .finally(() => {
      loading.value = false
    })
}
//获取websockt 地址
const getWsUrl = () => {
  http('/znjszd3/ht/jsdm/getWsForJsdm', 'get')
    .then((res) => {
      wsData = res.data
    })
    .finally(() => {})
}
const connectStomp = () => {
  clearTimeout(timer)
  if (stompClient !== null) {
    stompClient.disconnect()
  }
  const ws = new WebSocket(wsData.wsUrl)
  stompClient = Stomp.over(ws)
  // stompClient.heartbeat.outgoing = 60000
  // stompClient.heartbeat.incoming = 60000
  stompClient.debug = () => {}
  stompClient.connect(
    { username: '' },
    () => {
      stompClient.subscribe(wsData.wsDestination, function (message) {
        const msg = JSON.parse(message.body)
        console.log(msg)
        if (msg.doWhat == 'jsdming') {
          const index = jshList.value.findIndex((item) => item.jsh == msg.jsh)
          const room = jshList.value[index]
          room.doWhat = msg.doWhat
          room.status = msg.msg
        } else if (msg.doWhat == 'rydmResult') {
          const index = jshList.value.findIndex((item) => item.jsh == msg.data.jsh)
          const room = jshList.value[index]
          if (msg.data.bdjgzw == '成功') {
            if (room.success) {
              room.success = room.success * 1 + 1
            } else {
              room.success = 1
            }
            const index = callingList.value.findIndex((item) => item.rybh == msg.data.rybh)
            const person = callingList.value[index]
            person.bdjg = msg.data.bdjgzw
            person.bdtpurl = msg.data.bdtpbase64 ? 'data:image/png;base64,' + msg.data.bdtpbase64 : ''
            callingList.value.splice(index, 1, person)
          } else {
            if (room.fail) {
              room.fail = room.fail * 1 + 1
            } else {
              room.fail = 1
            }
            const index = callingList.value.findIndex((item) => item.rybh == msg.data.rybh)
            const person = callingList.value[index]
            person.bdjg = msg.data.bdjgzw
            person.bdtpurl = msg.data.bdtpbase64 ? 'data:image/png;base64,' + msg.data.bdtpbase64 : ''
            callingList.value.splice(index, 1, person)
          }
          jshList.value.splice(index, 1, room)
        } else if (msg.doWhat == 'jsdmFinish') {
          const index = jshList.value.findIndex((item) => item.jsh == msg.data.jsh)
          const room = jshList.value[index]
          room.doWhat = msg.doWhat
          room.status = msg.data.jsztzw
        }
      })
    },
    () => {
      console.log('stomp断开了')
      timer = setTimeout(() => {
        connectStomp()
      }, 2000)
    }
  )
}
//选择监室
const selectRoom = (item) => {
  item.selected = !item.selected
}
//全选
const selectAll = () => {
  if (!isSelectedAll.value) {
    jshList.value.forEach((item) => {
      item.selected = true
      isSelectedAll.value = true
    })
  } else {
    jshList.value.forEach((item) => {
      item.selected = false
      isSelectedAll.value = false
    })
  }
}
//清除选中
const clearSelect = () => {
  jshList.value.forEach((item) => {
    item.selected = false
    isSelectedAll.value = false
  })
}
//开始点名
const start = () => {
  const jshs = []
  jshList.value.forEach((item) => {
    if (item.selected) {
      item.starting = true
      item.success = 0
      item.fail = 0
      jshs.push(item.jsh)
    }
  })
  if (jshs.length == 0) return ElMessage.warning('请先选择监室')
  loading.value = true
  http(
    '/znjszd3/ht/jsdm/sddm',
    'post',
    {
      jshs: jshs.join()
    },
    false
  )
    .then((res) => {
      if (res.status == 200) {
        connectStomp()
        isStart.value = true
        ElMessage.success(res.message[0])
        callingNumber.value = res.data.total
        // jshList.value.forEach((item) => (item.selected = false))
        const ids = res.data.dmjsInfo

        for (const key in ids) {
          jshList.value.find((item) => {
            if (item.jsh == key) {
              item.dmjsid = ids[key]
              return
            }
          })
        }
      }
    })
    .finally(() => {
      loading.value = false
    })
}
const view = (item) => {
  dialogVisible.value = true
  http('/znjszd3/ht/jsdm/getDmryjlListByDmjsid', 'get', {
    dmjsid: item.dmjsid
  }).then((res) => {
    callingList.value = res.data
  })
}
//页面刷新时断开wesocket
const handleBeforeunload = (e) => {
  if (stompClient !== null) {
    stompClient.disconnect()
    // e.preventDefault()
  }
}
</script>
<style lang="scss" scoped>
.manual-call-name {
  ::v-deep(.custom-search) {
    .search-btn {
      grid-area: 1 / 2 / span 1 / span 3;
    }
  }
  .icon-quanxuan,
  .icon-kaishi1 {
    margin-right: 4px;
  }
  .box {
    margin-top: 10px;
    min-height: 895px;
    text-align: center;
    background-color: #fff;

    box-shadow: var(--el-box-shadow-light);
    border-radius: 4px;
    .calling {
      height: 60px;
      line-height: 60px;
      text-align: center;
      font-weight: 700;
      font-size: 24px;
      border-bottom: 1px solid var(--el-border-color);
      span {
        font-weight: 700;
      }
    }
  }
  .wrap {
    padding: 15px;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-auto-rows: 220px;
    gap: 10px;

    .room {
      position: relative;
      border: 2px solid var(--el-color-primary-light-5);
      border-radius: 4px;
      cursor: pointer !important;
      overflow: hidden;
      &:hover {
        box-shadow: 0 0 10px var(--el-color-primary-light-5);
      }
      .selected-label {
        position: absolute;
        right: -15px;
        top: -6px;
        width: 40px;
        height: 24px;
        background: var(--el-color-primary);
        text-align: center;
        transform: rotate(45deg);
        .el-icon {
          font-size: 12px;
          margin-top: 11px;
          transform: rotate(-45deg);
        }
      }
      .room-name {
        position: relative;
        height: 50px;
        font-size: 20px;
        font-weight: 700;
        border-bottom: var(--el-border);
        background: linear-gradient(90deg, var(--el-color-primary-light-9), rgba(158, 177, 242, 0.108) 99%);
        user-select: none;
        .el-button {
          position: absolute;
          top: 13px;
          right: 20px;
        }
      }
      .room-detail {
        position: relative;
        height: calc(100% - 50px);
        display: flex;
        color: #3d3d3d;
        .success,
        .fail {
          width: 85px;
          border-radius: 4px;
          font-size: 22px;
          font-weight: 700;
          text-align: center;
          > div {
            font-size: 16px;
            font-weight: 400;
            position: relative;
            top: -5px;
          }
        }
        .success {
          margin-top: 15px;
          color: #67c23a;
          border: 1px dashed #67c23a;
        }
        .fail {
          margin-top: 15px;
          color: red;
          border: 1px dashed red;
        }
        .status {
          position: absolute;
          left: 18px;
          bottom: 5px;
        }
      }
    }
  }
}
</style>
